/*
 * Copyright (c) 2011-2020, Peter Abeles. All Rights Reserved.
 *
 * This file is part of BoofCV (http://boofcv.org).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package boofcv.alg.filter.convolve.border;

import boofcv.generate.AutoTypeImage;
import boofcv.generate.CodeGeneratorBase;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;


/**
 * @author Peter Abeles
 */
public class GenerateConvolveWithBorderSparse extends CodeGeneratorBase {
	String className = "ConvolveWithBorderSparse";

	PrintStream out;

	String sumType;
	String bitWise;
	String kernelType;

	public GenerateConvolveWithBorderSparse() throws FileNotFoundException {
		out = new PrintStream(new FileOutputStream(className + ".java"));
	}

	@Override
	public void generateCode() throws FileNotFoundException {
		printPreamble();

		printFuncs(AutoTypeImage.F32);
		printFuncs(AutoTypeImage.I);

		out.print("\n" +
				"}\n");
	}

	private void printPreamble() {
		out.print(CodeGeneratorBase.copyright);
		out.print("package boofcv.alg.filter.convolve;\n" +
				"\n" +
				"import boofcv.core.image.border.ImageBorder_F32;\n" +
				"import boofcv.core.image.border.ImageBorder_I32;\n" +
				"import boofcv.struct.convolve.Kernel1D_F32;\n" +
				"import boofcv.struct.convolve.Kernel1D_I32;\n" +
				"import boofcv.struct.convolve.Kernel2D_F32;\n" +
				"import boofcv.struct.convolve.Kernel2D_I32;\n" +
				"\n" +
				"/**\n" +
				" * <p>\n" +
				" * Implementations of sparse convolve using image border.\n" +
				" * </p>\n" +
				" * \n" +
				" * <p>\n" +
				" * DO NOT MODIFY: Generated by {@link boofcv.alg.filter.convolve.border.GenerateConvolveWithBorderSparse}.\n" +
				" * </p>\n" +
				" * \n" +
				" * @author Peter Abeles\n" +
				" */\n" +
				"public class "+className+" {\n\n");
	}

	private void printFuncs( AutoTypeImage imageIn ) {

		sumType = imageIn.getSumType();
		bitWise = imageIn.getBitWise();

		if( imageIn.isInteger() ) {
			if( imageIn.getNumBits() <= 32 )
				kernelType = "I32";
			else
				kernelType = "I64";
		} else {
			kernelType = "F"+imageIn.getNumBits();
		}

		printHorizontal();
		printVertical();
		printConvolve();
	}

	private void printHorizontal() {
		out.print("\tpublic static "+sumType+" horizontal( Kernel1D_"+kernelType+" kernel, ImageBorder_"+kernelType+" input , int x , int y ) {\n" +
				"\t\tfinal int r = kernel.getRadius();\n" +
				"\t\tfinal int w = kernel.getWidth();\n" +
				"\n" +
				"\t\t"+sumType+" total = 0;\n" +
				"\n" +
				"\t\tfor( int i = 0; i < w; i++ ) {\n" +
				"\t\t\ttotal += input.get(x+i-r,y)*kernel.get(i);\n" +
				"\t\t}\n" +
				"\n" +
				"\t\treturn total;\n" +
				"\t}\n\n");
	}

	private void printVertical() {
		out.print("\tpublic static "+sumType+" vertical( Kernel1D_"+kernelType+" kernel, ImageBorder_"+kernelType+" input , int x , int y ) {\n" +
				"\t\tfinal int r = kernel.getRadius();\n" +
				"\t\tfinal int w = kernel.getWidth();\n" +
				"\n" +
				"\t\t"+sumType+" total = 0;\n" +
				"\n" +
				"\t\tfor( int i = 0; i < w; i++ ) {\n" +
				"\t\t\ttotal += input.get(x,y+i-r)*kernel.get(i);\n" +
				"\t\t}\n" +
				"\n" +
				"\t\treturn total;\n" +
				"\t}\n\n");
	}

	private void printConvolve() {
		out.print("\tpublic static "+sumType+" convolve( Kernel2D_"+kernelType+" kernel, ImageBorder_"+kernelType+" input , int x , int y ) {\n" +
				"\t\tfinal int r = kernel.getRadius();\n" +
				"\t\tfinal int w = kernel.getWidth();\n" +
				"\n" +
				"\t\t"+sumType+" total = 0;\n" +
				"\n" +
				"\t\tfor( int i = 0; i < w; i++ ) {\n" +
				"\t\t\tfor( int j = 0; j < w; j++ ) {\n" +
				"\t\t\t\ttotal += input.get(x+j-r,y+i-r)*kernel.get(i,j);\n" +
				"\t\t\t}\n" +
				"\t\t}\n" +
				"\n" +
				"\t\treturn total;\n" +
				"\t}\n\n");
	}

	public static void main( String[] args ) throws FileNotFoundException {
		GenerateConvolveWithBorderSparse app = new GenerateConvolveWithBorderSparse();
		app.generateCode();
	}
}
